package com.ruoyi.web.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.zip.ZipUtils;
import com.ruoyi.framework.web.domain.FiltVo;
import com.ruoyi.framework.web.domain.excel.Total;
import com.ruoyi.web.easyExcel.NoModelDataListener;
import com.ruoyi.framework.web.domain.excel.FileInfo;
import com.ruoyi.web.easyExcel.NoModelDataListener2;
import com.ruoyi.web.mapper.FileInfoMapper;
import com.ruoyi.web.mapper.TotalMapper;
import com.ruoyi.web.service.IExcelService;
import com.ruoyi.web.spireExcel.ExcelFilter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.zip.ZipOutputStream;

/**
 * @author GuoX
 */
@Slf4j
@Service
public class ExcelServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements IExcelService {
    /**文件保存路径*/
    @Value("${excel.directory}")
    private String directory;
    @Value("${excel.directoryOfFilted}")
    private String directoryOfFilted;

    @Autowired
    private FileInfoMapper fileInfoMapper;
    @Autowired
    private TotalMapper totalMapper;
    @Override
    public AjaxResult add(MultipartFile file) {
        //保存文件
        File f=new File(directory+file.getOriginalFilename());
        if(!f.getParentFile().exists()){
            f.getParentFile().mkdirs();
        }

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(file.getInputStream());
            bos = new BufferedOutputStream(Files.newOutputStream(f.toPath()));
            byte[] buffer = new byte[20480];
            int bytesRead = 0;
            while ((bytesRead = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
            }
            bos.flush();
            bis.close();
            bos.close();
            //保存文件信息
            FileInfo fileInfo =new FileInfo();
            fileInfo
                    .setOriginName(file.getOriginalFilename())
                    .setSize(this.getSize(file.getSize()))
                    .setIsFilted("0")
                    .setUpdateTime(DateUtils.getNowDate())
                    .setCreateTime(DateUtils.getNowDate());
            QueryWrapper<FileInfo> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("origin_name",fileInfo.getOriginName());
            this.saveOrUpdate(fileInfo,queryWrapper);
            log.debug("--------------文件保存成功:{}--------------\n",file.getOriginalFilename());
            return AjaxResult.success("保存成功,"+file.getOriginalFilename());
        } catch (IOException e) {
            log.error("--------------文件保存失败:{}--------------\n{}",file.getOriginalFilename(),e.getMessage());
            return AjaxResult.error("文件保存失败:"+file.getOriginalFilename());
        }
//        try {
//            file.transferTo(f);
//            log.debug("--------------文件保存成功--------------");
//        } catch (IOException e) {
//            log.debug("--------------文件保存异常--------------\n{}",e.getMessage());
//            return AjaxResult.error("文件保存异常");
//        }

    }

    @Override
    public AjaxResult filt(FiltVo vo) {
        vo.getFileIds().forEach(i->{
            FileInfo fileInfo=fileInfoMapper.selectById(i);
            File file=new File(directory+fileInfo.getOriginName());
            if(file.exists()){
                //修改文件状态为正在筛选
                fileInfo.setIsFilted("2");
                this.updateById(fileInfo);
                //easyExcel筛选
                    // call the void method here
                    EasyExcel.read(file,new NoModelDataListener2(directory,directoryOfFilted+"/(已筛选)"+fileInfo.getOriginName(),fileInfo,fileInfoMapper,vo.getNumbers())).sheet().doRead();
//                //spire.xls筛选
//                ExcelFilter filter=new ExcelFilter(directory,directoryOfFilted+"/(已筛选)");
//                String directoryOfFilted1= filter.filt(fileInfo.getOriginName(),vo.getNumbers());
                   File filtedFile=new File(directoryOfFilted+"/(已筛选)"+fileInfo.getOriginName());
                   //easyExcel合计
                   EasyExcel.read(filtedFile,new NoModelDataListener(directoryOfFilted+"/(已筛选)",fileInfo.getId(),fileInfo.getOriginName(),vo.getNumbers(),totalMapper)).sheet().doRead();
            }else{
                log.error("文件不存在：{}",fileInfo.getOriginName());
            }
        });
        //统计所有
        composeResult(vo.getNumbers());
        return AjaxResult.success("成功");
    }

    @Override
    public AjaxResult remove(String[] fileId) {
        QueryWrapper<FileInfo> wrapper=new QueryWrapper<>();
        wrapper.in("id", Arrays.stream(fileId).toArray());
        wrapper.select("origin_name");
        List<FileInfo> infoList=fileInfoMapper.selectList(wrapper);
        List<String> nameList=infoList.stream().map(FileInfo::getOriginName).collect(Collectors.toList());
        for (String s : nameList) {
            File file=new File(directory+s);
            File file1=new File(directoryOfFilted+"/(已筛选)"+s);
            if (file.exists()&&file.isFile()){
                file.delete();
            }
            if(file1.exists()){
                file1.delete();
            }
        }
        QueryWrapper<Total> totalQueryWrapper=new QueryWrapper<>();
        totalQueryWrapper.in("file_id",Arrays.stream(fileId).toArray());
        totalMapper.delete(totalQueryWrapper);
      boolean f=this.removeBatchByIds(Arrays.asList(fileId)) ;
      if (f){
          return AjaxResult.success("删除成功");
      }
      return AjaxResult.error("删除失败");
    }

    @Override
    public  byte[]  download() {
        //打包文件为压缩包
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        try {
             ZipUtils.compress(Paths.get(directoryOfFilted).toString(),directoryOfFilted+".zip",zip);
            IOUtils.closeQuietly(zip);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return outputStream.toByteArray();
    }

    /**
     *  计算文件大小
     **/
    public String getSize(Long size) {
        if (size > (1024 )) {
                return size / 1024 + "KB";
        }else{
            return size+"B";
        }
    }
    /***
     * @Author GuoX
     * @Description 合并合计结果并导出文件
     * @Date 2023/6/19 17:15
     * @Param
     * @return
     **/
    private void composeResult(List<String> numbers){
        //生成表头
        List<List<String>> headlist = ListUtils.newArrayList();
        QueryWrapper<Total> totalQueryWrapper=new QueryWrapper<>();
        totalQueryWrapper.groupBy("project_name");
        List<Total> totalsGroup=totalMapper.selectList(totalQueryWrapper);
        List<String> head0=new ArrayList<>(1);
        head0.add("");
        headlist.add(head0);
        for (Total t : totalsGroup) {
            List<String> h=new ArrayList<>(1);
            h.add(t.getProjectName());
            headlist.add(h);
        }

        //生成数据
        List<Total> totals=totalMapper.selectList(null);

        List<List<Object>> dataList = ListUtils.newArrayList();
        //按渠道编码分行
        for (String number : numbers) {
            List<Object> data=ListUtils.newArrayList();
            data.add(number);
            for (Total total : totals) {
                for (List<String> strings : headlist) {
                    if (strings.get(0).equals(total.getProjectName()) && number.equals(total.getAccountNumber())) {
                        data.add(total.getTotal());
                    }
                }
            }
            double totalCount=0;
            for (int i = 1; i < data.size(); i++) {
                totalCount= totalCount+Double.parseDouble(data.get(i).toString());
            }
            data.add(totalCount);
            dataList.add(data);
        }
        //生成合计行
        List<Object> data=ListUtils.newArrayList();
        data.add("合计(元)");
        for (int i = 1; i < headlist.size(); i++) {
            double count=0;
            for (List<Object> list : dataList) {
                count=count+ Double.parseDouble(list.get(i).toString());
            }
            data.add(count);
        }
        double totalCount=0;
        for (int i = 1; i < data.size(); i++) {
            totalCount=totalCount+Double.parseDouble(data.get(i).toString());
        }
        data.add(totalCount);
        List<String> headZ=new ArrayList<>();
        headZ.add("总计(元)");
        headlist.add(headZ);
        dataList.add(data);

        //生成表格
        File file=new File(directoryOfFilted+"/统计.xlsx");
        try (ExcelWriter excelWriter = EasyExcel.write(file).build()) {
            WriteSheet sheet=EasyExcel.writerSheet(1,"统计").head(headlist).build();
            excelWriter.write(dataList,sheet);
            excelWriter.finish();
        }
    }


}
